千鳥アニメーション
千鳥アニメーションは、視覚的な変化という単純なコンセプトです。 一度にではなく、一連の操作として実行されます。 アニメーションは純粋にシーケンシャルであり、その後に 1 つの変更が発生する場合があります。 あるいは、部分的または完全に重複する可能性があります。それはまたかもしれません 変化が起こらないギャップがあります。
このガイドでは、Flutter で千鳥アニメーションを構築する方法を説明します。
次のビデオは、によって実行されるアニメーションを示しています。 Basic_staggered_animation:
ビデオでは、単一のウィジェットの次のアニメーションが表示されます。 これは、わずかに丸い角を持つ、縁取りされた青い正方形として始まります。 四角形は次の順序で変化します。
- フェードイン
- 広がる
- 上に移動すると背が高くなります
- 縁取りされた円に変形します
- オレンジ色に色が変わります
順方向に実行した後、アニメーションは逆方向に実行されます。
千鳥アニメーションの基本構造
次の図は、Interval
で使用されるBasic_staggered_animation例。
次のような特徴に気づくかもしれません。
- 不透明度はタイムラインの最初の 10% で変化します。
- 不透明度の変化の間にはわずかな隙間が生じますが、 そして幅の変化。
- タイムラインの最後の 25% では何もアニメーションしません。
- パディングを増やすと、ウィジェットが上に盛り上がって見えるようになります。
- 境界線の半径を 0.5 に増やすと、 角の丸い正方形を円に変換します。
- パディングと高さの変更は、 まったく同じ間隔ですが、そうする必要はありません。
アニメーションを設定するには:
- を作成します
AnimationController
すべてを管理するのは、Animations
。 - を作成します
Tween
アニメーション化されるプロパティごとに。- の
Tween
値の範囲を定義します。 - の
Tween
のanimate
メソッドには、parent
コントローラーを生成し、Animation
その物件のために。
- の
- で間隔を指定します。
Animation
のcurve
財産。
制御アニメーションの値が変化すると、 新しいアニメーションの値が変化し、UI の更新がトリガーされます。
次のコードは、width
財産。
それは、CurvedAnimation
、
緩和カーブを指定します。見るCurves
ために
その他の利用可能な事前定義されたアニメーション カーブ。
width = Tween<double>( begin: 50.0, end: 150.0, ).animate( CurvedAnimation( parent: controller, curve: Interval( 0.125, 0.250, curve: Curves.ease, ), ), ),
のbegin
とend
値は倍精度である必要はありません。
次のコードは、borderRadius
財産
(正方形の角の丸みを制御します)、
を使用してBorderRadius.circular()
。
borderRadius = BorderRadiusTween(
begin: BorderRadius.circular(4),
end: BorderRadius.circular(75),
).animate(
CurvedAnimation(
parent: controller,
curve: Interval(
0.375, 0.500,
curve: Curves.ease,
),
),
),
完全な千鳥アニメーション
すべてのインタラクティブなウィジェットと同様に、完全なアニメーションは次の構成になっています。 ウィジェットのペア: ステートレス ウィジェットとステートフル ウィジェット。
ステートレス ウィジェットは、Tween
さん、
を定義しますAnimation
オブジェクトを提供し、build()
関数
ウィジェット ツリーのアニメーション部分の構築を担当します。
ステートフル ウィジェットはコントローラーを作成し、アニメーションを再生し、 そして、ウィジェット ツリーの非アニメーション部分を構築します。 画面内のどこかでタップが検出されるとアニメーションが始まります。
Basic_staggered_animation の main.dart の完全なコード
ステートレス ウィジェット: StaggerAnimation
ステートレスウィジェットでは、StaggerAnimation
、
のbuild()
関数はインスタンスを作成しますAnimatedBuilder
- 構築用の汎用ウィジェット
アニメーション。のAnimatedBuilder
ウィジェットを構築し、それを使用して設定します。Tweens
' 現在の値。
この例では、という名前の関数を作成します。_buildAnimation()
(実行するのは
実際の UI 更新)、それをそのbuilder
財産。
AnimatedBuilder はアニメーション コントローラーからの通知をリッスンし、
値の変化に応じてウィジェット ツリーにダーティのマークを付けます。
アニメーションのティックごとに値が更新されます。
その結果、_buildAnimation()
。
class StaggerAnimation extends StatelessWidget { StaggerAnimation({ Key key, this.controller }) : // Each animation defined here transforms its value during the subset // of the controller's duration defined by the animation's interval. // For example the opacity animation transforms its value during // the first 10% of the controller's duration. opacity = Tween<double>( begin: 0.0, end: 1.0, ).animate( CurvedAnimation( parent: controller, curve: Interval( 0.0, 0.100, curve: Curves.ease, ), ), ), // ... Other tween definitions ... super(key: key); final AnimationController controller; final Animation<double> opacity; final Animation<double> width; final Animation<double> height; final Animation<EdgeInsets> padding; final Animation<BorderRadius> borderRadius; final Animation<Color> color; // This function is called each time the controller "ticks" a new frame. // When it runs, all of the animation's values will have been // updated to reflect the controller's current value. Widget _buildAnimation(BuildContext context, Widget child) { return Container( padding: padding.value, alignment: Alignment.bottomCenter, child: Opacity( opacity: opacity.value, child: Container( width: width.value, height: height.value, decoration: BoxDecoration( color: color.value, border: Border.all( color: Colors.indigo[300], width: 3.0, ), borderRadius: borderRadius.value, ), ), ), ); } @override Widget build(BuildContext context) { return AnimatedBuilder( builder: _buildAnimation, animation: controller, ); } }
ステートフル ウィジェット: StaggerDemo
ステートフルなウィジェット、StaggerDemo
、を作成します。AnimationController
(すべてを支配する者)、2000 ミリ秒の期間を指定します。遊びます
アニメーションを作成し、ウィジェット ツリーの非アニメーション部分を構築します。
画面内でタップが検出されるとアニメーションが始まります。
アニメーションは前方に実行され、次に後方に実行されます。
class StaggerDemo extends StatefulWidget { @override _StaggerDemoState createState() => _StaggerDemoState(); } class _StaggerDemoState extends State<StaggerDemo> with TickerProviderStateMixin { AnimationController _controller; @override void initState() { super.initState(); _controller = AnimationController( duration: const Duration(milliseconds: 2000), vsync: this ); } // ...Boilerplate... Future<void> _playAnimation() async { try { await _controller.forward().orCancel; await _controller.reverse().orCancel; } on TickerCanceled { // the animation got canceled, probably because it was disposed of } } @override Widget build(BuildContext context) { timeDilation = 10.0; // 1.0 is normal animation speed. return Scaffold( appBar: AppBar( title: const Text('Staggered Animation'), ), body: GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { _playAnimation(); }, child: Center( child: Container( width: 300.0, height: 300.0, decoration: BoxDecoration( color: Colors.black.withOpacity(0.1), border: Border.all( color: Colors.black.withOpacity(0.5), ), ), child: StaggerAnimation( controller: _controller.view ), ), ), ), ); } }